package model;
import java.util.List;

import model.common.Constantes;
import model.movimiento.*;
import model.objetos.Objetos;
import model.posicion.Posicion;
import excepciones.ObjetoComidoException;
import ar.uba.fi.algo3.titiritero.ObjetoVivo;
import ar.uba.fi.algo3.titiritero.Posicionable;

public class Pacman implements Movible, Posicionable, ObjetoVivo {

	private Posicion posicion;
	private Laberinto elLaberinto;
	private Movimientos direccion;
	public Movimientos direccionActualizar;
	private int velocidad;
	private int x;
	private int y;

	public Pacman(Laberinto elLaberinto, Movimientos izquierda) { 
		
			this.posicion=elLaberinto.getInicioPacman();
			this.elLaberinto=elLaberinto;
			this.direccion = this.direccionActualizar = izquierda;
			this.velocidad=Constantes.VELOCIDAD;
			this.actualizarVista();			
	}
	
	public void reiniciar(){
		
		this.posicion=this.elLaberinto.getInicioPacman();
		this.actualizarVista();
	}

	private void actualizarVista() {

		this.x=posicion.getPosX() * (Constantes.ANCHO)+(Constantes.ANCHO%2);
		this.y=posicion.getPosY() * (Constantes.ALTO)+(Constantes.ALTO%2);
		
	}

	public void mover(Posicion posicion) {
		this.posicion = elLaberinto.avanzar(posicion,direccion);
		try {
			this.comer(this.posicion);			
		}
		catch (ObjetoComidoException e){
			//que hago con la excepcion?
		}
		this.actualizarVista();
	}
	public void pisar() {
		
		try {
			this.comer(this.posicion);			
		}
		catch (ObjetoComidoException e){
			//que hago con la excepcion?
		}
	}
	
	//agregue este nuevo metodo en Pacman y saque el metodo comerPacman.
	public void comer(Posicion posicion){
		Objetos[][] tablero = this.elLaberinto.getTablero();
		tablero[posicion.getPosX()][posicion.getPosY()].comer(posicion);
	}

	public void actualizarDireccion(Movimientos direccion) {
		this.direccion=direccion;
	}

	public Posicion getPosicion() {		
		return posicion;
	}
	
	public int getX() {
		return this.x;
	}

	public int getY() {
		return this.y;
	}
	public void vivir() {
		
		List<Movimientos> movimientos;
		movimientos=elLaberinto.movimientosPosibles(this.posicion);
		if(this.sePuede(movimientos, this.direccionActualizar)){
			if(this.elLaberinto.interseccion(movimientos, this.direccionActualizar)){
				if(this.enMedio()){
					this.direccion= this.direccionActualizar;
				}
			}else
				this.direccion= this.direccionActualizar;
			
		}
		if (this.sePuede(movimientos,this.direccion)){
			this.x+=this.direccion.sentidoX()*this.velocidad;
			this.y+=this.direccion.sentidoY()*this.velocidad;
		}else{
			if(!this.enMedio()){
				this.x+=this.direccion.sentidoX()*this.velocidad;
				this.y+=this.direccion.sentidoY()*this.velocidad;
			}
		}
		Posicion posAux = new Posicion((int)Math.floor(this.x/Constantes.ANCHO),(int)Math.floor(this.y /Constantes.ALTO));
		if(!this.posicion.equals(posAux)){
			if(this.enMedio(posAux))this.mover(this.posicion);
		}
		//this.pisar();
	}
	

	private boolean enMedio(Posicion posAux) {
		
		boolean posX=false,posY=false;
		if( Math.abs(( this.x - ((posAux.getPosX() * Constantes.ANCHO)+(Constantes.ANCHO%2)) ) ) < this.velocidad ) posX=true;
		if( Math.abs(( this.y - ((posAux.getPosY() * Constantes.ALTO)+(Constantes.ALTO%2)) ) )  < this.velocidad ) posY=true;
		if(posX && posY){
			return true;
		}
		return false;
	}

	private boolean sePuede(List<Movimientos> movimientos, Movimientos movimiento) {
		for(int i=0; i<movimientos.size();i++){
			if((movimientos.get(i).movimientoString().equals(movimiento.movimientoString()))) 
				return true;
		}
		return false;
	}

	
	
	private boolean enMedio() {
		
		boolean posX=false,posY=false;
		if( Math.abs(( this.x - ((this.getPosicion().getPosX() * Constantes.ANCHO)+(Constantes.ANCHO%2)) ) ) < this.velocidad ) posX=true;
		if( Math.abs(( this.y - ((this.getPosicion().getPosY() * Constantes.ALTO)+(Constantes.ALTO%2)) ) )  < this.velocidad ) posY=true;
		if(posX && posY){
			this.x=this.getPosicion().getPosX() * Constantes.ANCHO+(Constantes.ANCHO%2);
			this.y=this.getPosicion().getPosY() * Constantes.ALTO+(Constantes.ALTO%2);
			return true;
		}
		return false;
	}

	public Movimientos getDireccion() {
		
		return this.direccion;
	}


		
}
